package cloud.lysky.java.on.concurrent.AQS;

import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;

/**
 * @author luoly
 * @describe
 * @date 2023/3/24 11:00
 **/
// 基于AQS 实现同步锁
public class MyLock {
    private final Sync sync;

    public MyLock(){
        sync = new Sync();
    }


    //静态内部类，继承AQS
    private static class Sync extends AbstractQueuedLongSynchronizer {

        //是否处于占用状态
        @Override
        protected boolean isHeldExclusively() {
            //当前状态为1则表示已被占用
            return getState() == 1;
        }

        //当状态为0的时候获取锁
        @Override
        protected boolean tryAcquire(long acquires) {
            //这里限定只能为1个量
            assert acquires == 1;
            if (compareAndSetState(0,1)){ // 如果当前状态为0，则设置获取锁
                //设置当前线程独占资源
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        //释放锁，将状态设置为0

        @Override
        protected boolean tryRelease(long releases) {
            //限定为1个量
            assert releases == 1;
            if (getState() == 0)
                //如果当前状态为0，则说明没有被占用，抛出异常
                throw new IllegalMonitorStateException();
            // 清空独占线程
            setExclusiveOwnerThread(null);
            // 设置状态为0
            setState(0);
            return true;
        }
        // 同步对象完成一系列复杂的操作，我们仅需指向它即可
        private final Sync sync = new Sync();

        public void lock() {
            //独占式获取锁，如果失败则加入等待队列
            sync.acquire(1);
        }

        public boolean tryLock(){
            // 独占式获取锁，立即返回。成功返回true, 否则为false。
            return sync.tryAcquire(1);
        }

        public void unlock() {
            // 独占式释放锁
            sync.release(1);
        }

        public boolean isLocked() {
            // 当前同步器是否处于占用状态
            return sync.isHeldExclusively();
        }
    }
}
